//
//  ECViewLayoutBuffer.swift
//  EasyCoding
//
//  Created by JY_NEW on 2021/8/18.
//

import UIKit

// MARK:  单视图处理

/// 缓存布局信息
public class ECViewLayoutBuffer {
    let view: UIView
    private(set) var layouts: [(refer: ECViewLayoutReference,layout: ECViewLayout)] = []
    init(view: UIView) {
        self.view = view
    }
    func add(layouts: [ECViewLayout], for refer: ECViewLayoutReference) {
        for layout in layouts {
            self.layouts.append((refer: refer, layout: layout))
        }
    }
    /// 应用布局
    func apply() {
        for layout in self.layouts {
            layout.layout.apply(to: self.view, refer: layout.refer.layoutReference(for: self.view))
        }
    }
}

extension EasyCoding where Base: UIView {
    /// 添加布局，但在调用apply前不会应用
    public func layout(for refer: ECViewLayoutReference = .default, _ layouts:ECViewLayout...) -> ECViewLayoutBuffer {
        let buffer = ECViewLayoutBuffer(view: self.base)
        buffer.add(layouts: layouts, for: refer)
        return buffer
    }
    public func layout(for view: UIView, _ layouts:ECViewLayout...) -> ECViewLayoutBuffer {
        let buffer = ECViewLayoutBuffer(view: self.base)
        buffer.add(layouts: layouts, for: .specify(view))
        return buffer
    }
    ///应用布局
    @discardableResult
    public func applyLayout(for refer: ECViewLayoutReference = .default, _ layouts:ECViewLayout...) -> Self {
        let buffer = ECViewLayoutBuffer(view: self.base)
        buffer.add(layouts: layouts, for: refer)
        buffer.apply()
        return self
    }
    @discardableResult
    public func applyLayout(for view: UIView, _ layouts:ECViewLayout...) -> Self {
        let buffer = ECViewLayoutBuffer(view: self.base)
        buffer.add(layouts: layouts, for: .specify(view))
        buffer.apply()
        return self
    }
}
extension ECViewLayoutBuffer {
    public func layout(for refer: ECViewLayoutReference = .default, _ layouts:ECViewLayout...) -> ECViewLayoutBuffer {
        self.add(layouts: layouts, for: refer)
        return self
    }
    public func layout(for view: UIView, _ layouts:ECViewLayout...) -> ECViewLayoutBuffer {
        self.add(layouts: layouts, for: .specify(view))
        return self
    }
}

// MARK:  多视图(数组)处理

/// 缓存布局信息
public class ECViewLayoutArrayBuffer {
    let views: [UIView]
    private(set) var firstLayouts: [ECViewLayout] = []
    private(set) var betweenLayouts: [ECViewLayout] = []
    private(set) var lastLayouts: [ECViewLayout] = []
    /// 全部布局默认针对父控件
    private(set) var allLayouts: [ECViewLayout] = []
    
    init(views: [UIView]) {
        self.views = views
    }
    func add(first layouts: [ECViewLayout]) {
        self.firstLayouts.append(contentsOf: layouts)
    }
    func add(between layouts: [ECViewLayout]) {
        self.betweenLayouts.append(contentsOf: layouts)
    }
    func add(last layouts: [ECViewLayout]) {
        self.lastLayouts.append(contentsOf: layouts)
    }
    func add(all layouts: [ECViewLayout]) {
        self.allLayouts.append(contentsOf: layouts)
    }
    /// 应用布局
    func apply() {
        if self.views.count > 0 {
            let first = self.views.first!
            let last = self.views.last!
            let sp = first.superview!
            let firstRef = first.easy.previous()?.base ?? sp
            let lastRef = first.easy.next()?.base ?? sp

            self.firstLayouts.apply(to: first, refer: firstRef)
            self.views.easy.forEachNeighbor { previous, next in
                self.betweenLayouts.apply(to: previous, refer: next)
            }
            self.lastLayouts.apply(to: last, refer: lastRef)
            self.allLayouts.apply(to: self.views, refer: sp)
        }
    }
}

extension EC.NamespaceArrayImplement where Element: UIView {
    /// 添加布局，但在调用apply前不会应用
    public func layout(first layouts:ECViewLayout...) -> ECViewLayoutArrayBuffer {
        let buffer = ECViewLayoutArrayBuffer(views: self.base)
        buffer.add(first: layouts)
        return buffer
    }
    /// 添加布局，但在调用apply前不会应用
    public func layout(between layouts:ECViewLayout...) -> ECViewLayoutArrayBuffer {
        let buffer = ECViewLayoutArrayBuffer(views: self.base)
        buffer.add(between: layouts)
        return buffer
    }
    /// 添加布局，但在调用apply前不会应用
    public func layout(last layouts:ECViewLayout...) -> ECViewLayoutArrayBuffer {
        let buffer = ECViewLayoutArrayBuffer(views: self.base)
        buffer.add(last: layouts)
        return buffer
    }
    public func layout(all layouts:ECViewLayout...) -> ECViewLayoutArrayBuffer {
        let buffer = ECViewLayoutArrayBuffer(views: self.base)
        buffer.add(all: layouts)
        return buffer
    }
}
extension ECViewLayoutArrayBuffer {
    /// 添加布局，但在调用apply前不会应用
    public func layout(first layouts:ECViewLayout...) -> ECViewLayoutArrayBuffer {
        self.add(first: layouts)
        return self
    }
    /// 添加布局，但在调用apply前不会应用
    public func layout(between layouts:ECViewLayout...) -> ECViewLayoutArrayBuffer {
        self.add(between: layouts)
        return self
    }
    /// 添加布局，但在调用apply前不会应用
    public func layout(last layouts:ECViewLayout...) -> ECViewLayoutArrayBuffer {
        self.add(last: layouts)
        return self
    }
    /// 添加布局，但在调用apply前不会应用
    public func layout(all layouts:ECViewLayout...) -> ECViewLayoutArrayBuffer {
        self.add(all: layouts)
        return self
    }
}

#if EASY_SHORTCUT

extension UIView {
    /// 添加布局，但在调用apply前不会应用
    public func layout(for refer: ECViewLayoutReference = .default, _ layouts:ECViewLayout...) -> ECViewLayoutBuffer {
        let buffer = ECViewLayoutBuffer(view: self)
        buffer.add(layouts: layouts, for: refer)
        return buffer
    }
    public func layout(for view: UIView, _ layouts:ECViewLayout...) -> ECViewLayoutBuffer {
        let buffer = ECViewLayoutBuffer(view: self)
        buffer.add(layouts: layouts, for: .specify(view))
        return buffer
    }
    ///应用布局
    @discardableResult
    public func applyLayout(for refer: ECViewLayoutReference = .default, _ layouts:ECViewLayout...) -> Self {
        let buffer = ECViewLayoutBuffer(view: self)
        buffer.add(layouts: layouts, for: refer)
        buffer.apply()
        return self
    }
    @discardableResult
    public func applyLayout(for view: UIView, _ layouts:ECViewLayout...) -> Self {
        let buffer = ECViewLayoutBuffer(view: self)
        buffer.add(layouts: layouts, for: .specify(view))
        buffer.apply()
        return self
    }
}

#endif
